/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
limitations under the License.*/

package zuo.biao.library.manager;

import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import zuo.biao.library.util.Log;

import java.util.*;

/**时间刷新器
 * @author Lemon
 * 		在使用TimeRefresher的Context被销毁前TimeRefresher.getInstance().removeTimeRefreshListener(...);
 *      在应用退出前TimeRefresher.getInstance().finish();
 */
public class TimeRefresher {
    private static final String TAG = "TimeRefresher";

    /**
     * 回调接口
     */
    public interface OnTimeRefreshListener {
        void onTimerStart();

        void onTimerRefresh();

        void onTimerStop();
    }

    private Map<String, TimeHolder> refreshMap;

    private TimeRefresher() {
        refreshMap = new HashMap<String, TimeHolder>();
    }

    private static TimeRefresher instance;

    /**
     * 单例模式
     * @return r
     */
    public static TimeRefresher getInstance() {
        if (instance == null) {
            synchronized (TimeRefresher.class) {
                if (instance == null) {
                    instance = new TimeRefresher();
                }
            }
        }
        return instance;
    }

    /**
     * 是否包含
     * @param tag t
     * @return boolean
     */
    public boolean isContain(String tag) {
        return tag != null && refreshMap != null && refreshMap.containsKey(tag);
    }

    /**
     * 开始启动刷新
     * @param tag t
     * @param listener l
     */
    public synchronized void addTimeRefreshListener(String tag, OnTimeRefreshListener listener) {
        addTimeRefreshListener(tag, 1000, listener);
    }

    /**
     * 开始启动
     * @param tag t
     * @param duration d
     * @param listener l
     */
    public synchronized void addTimeRefreshListener(String tag, long duration, OnTimeRefreshListener listener) {
        if (duration > 0 && tag != null && listener != null) {
            Log.debug(TAG, "\n addTimeRefreshListener  duration > 0 && tag = " + tag + " && listener != null >>");
            if (refreshMap.containsKey(tag) && refreshMap.get(tag) != null) {
                refreshMap.get(tag).startTimer();
                Log.debug(
                        TAG,
                        "refreshMap.containsKey(tag) && refreshMap.get(tag) != null >> "
                                + " refreshMap.get(tag).startTimer();");
            } else {
                refreshMap.put(tag, new TimeHolder(duration, listener));
                Log.debug(TAG, "addTimeRefreshListener  added tag = ");
            }
        }
        Log.debug(TAG, "addTimeRefreshListener  refreshMap.size() = " + refreshMap.size() + "");
    }

    /**
     * startTimeRefreshListener
     * @param tag t
     */
    public synchronized void startTimeRefreshListener(String tag) {
        TimeHolder holder = refreshMap.get("" + tag);
        if (holder != null) {
            holder.startTimer();
            Log.debug(TAG, "startTimeRefreshListener started tag = " + tag);
        }
    }

    /**
     * 停止时间
     * @param tag t
     */
    public synchronized void stopTimeRefreshListener(String tag) {
        TimeHolder holder = refreshMap.get("" + tag);
        if (holder != null) {
            holder.stopTimer();
            Log.debug(TAG, "stopTimeRefreshListener stopped tag = " + tag);
        }
    }

    /**
     * 移除时间
     * @param tag t
     */
    public synchronized void removeTimeRefreshListener(String tag) {
        TimeHolder holder = refreshMap.get("" + tag);
        if (holder != null) {
            holder.stopTimer();
            holder = null;
        }
        refreshMap.remove("" + tag);
        Log.debug(TAG, "removeTimeRefreshListener removed tag = " + tag);
    }

    /**
     * 完全结束Timer进程
     */
    public void finish() {
        if (refreshMap == null || refreshMap.size() <= 0) {
            Log.debug(TAG, "finish  refreshMap == null || refreshMap.size() <= 0 >> return;");
            return;
        }
        Set<String> tagSet = refreshMap.keySet();
        if (tagSet != null) {
            for (String tag : tagSet) {
                removeTimeRefreshListener(tag);
            }
        }
        refreshMap = null;
        Log.debug(TAG, "\n finish  finished \n");
    }

    /**
     * 计时器holder
     */
    static class TimeHolder {
        long duration = 1000;
        OnTimeRefreshListener listener;

        public TimeHolder(OnTimeRefreshListener listener) {
            this(1000, listener);
        }

        public TimeHolder(long duration, OnTimeRefreshListener listener) {
            this.duration = duration * 1000;
            this.listener = listener;
            startTimer();
        }

        Timer timer;
        TimerTask task;
        /**
         * 启动计时器
         */
        public void startTimer() {
            if (listener == null) {
                Log.error(TAG, "startTimer  listener == null >> return;");
                return;
            }

            stopTimer();

            listener.onTimerStart();
            if (timer == null) {
                timer = new Timer(true);
            }
            if (task == null) {
                task =
                        new TimerTask() {
                            /**
                             * 运行
                             */
                            public void run() {
                                handler.sendEvent(0);
                            }
                        };
            }
            timer.schedule(task, 0, duration); // 延时0ms后执行，1000ms执行一次
        }

        /**
         * 停止计时器
         */
        public void stopTimer() {
            if (listener != null) {
                listener.onTimerStop();
            }
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
            if (task != null) {
                task.cancel();
                task = null;
            }
        }

        final EventHandler handler =
                new EventHandler(EventRunner.getMainEventRunner()) {
                    @Override
                    protected void processEvent(InnerEvent event) {
                        super.processEvent(event);
                        listener.onTimerRefresh();
                    }
                };
    }
}
